<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.0.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/website/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/website/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/website/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/website/images/logo.svg" color="#222">
  <link rel="alternate" href="/website/atom.xml" title="徐良军" type="application/atom+xml">



<link rel="stylesheet" href="/website/css/main.css">


<link rel="stylesheet" href="/website/lib/font-awesome/css/font-awesome.min.css">


<script id="hexo-configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/website/',
    scheme: 'Gemini',
    version: '7.5.0',
    exturl: false,
    sidebar: {"position":"left","display":"post","offset":12,"onmobile":false},
    copycode: {"enable":false,"show_result":false,"style":null},
    back2top: {"enable":true,"sidebar":false,"scrollpercent":true},
    bookmark: {"enable":false,"color":"#222","save":"auto"},
    fancybox: false,
    mediumzoom: false,
    lazyload: false,
    pangu: false,
    algolia: {
      appID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    },
    localsearch: {"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},
    path: 'search.xml',
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    translation: {
      copy_button: '复制',
      copy_success: '复制成功',
      copy_failure: '复制失败'
    },
    sidebarPadding: 40
  };
</script>

  <meta name="description" content="在本次实验中我们将使用PaddlePaddle来搭建一个简单的线性回归模型，并利用这一模型预测你的储蓄（在某地区）可以购买多大面积的房子。并且在学习模型搭建的过程中，了解到机器学习的若干重要概念，掌握一个机器学习预测的基本流程。">
<meta name="keywords" content="-AI Studio -Paddle -线性回归">
<meta property="og:type" content="article">
<meta property="og:title" content="PaddlePaddle实现线性回归">
<meta property="og:url" content="https:&#x2F;&#x2F;ahxuliangjun.gitee.io&#x2F;website&#x2F;2019&#x2F;11&#x2F;15&#x2F;2&#x2F;index.html">
<meta property="og:site_name" content="徐良军">
<meta property="og:description" content="在本次实验中我们将使用PaddlePaddle来搭建一个简单的线性回归模型，并利用这一模型预测你的储蓄（在某地区）可以购买多大面积的房子。并且在学习模型搭建的过程中，了解到机器学习的若干重要概念，掌握一个机器学习预测的基本流程。">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="http:&#x2F;&#x2F;q0sn9so75.bkt.clouddn.com&#x2F;68.png">
<meta property="og:image" content="http:&#x2F;&#x2F;q0sn9so75.bkt.clouddn.com&#x2F;69.png">
<meta property="og:updated_time" content="2019-11-15T10:31:06.575Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http:&#x2F;&#x2F;q0sn9so75.bkt.clouddn.com&#x2F;68.png">

<link rel="canonical" href="https://ahxuliangjun.gitee.io/website/2019/11/15/2/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome: false,
    isPost: true,
    isPage: false,
    isArchive: false
  };
</script>

  <title>PaddlePaddle实现线性回归 | 徐良军</title>
  


  <script>
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?af6a4283c9604d2328cad2de26b72836";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>




  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

  <!-- weather css -->
  <style type="text/css">
	  #tp-weather-widget .sw-container {
	    left: 10px;
	    right: unset;
	    top: unset;
	    bottom: 10px;
	  }
  </style>
</head>

<body itemscope itemtype="http://schema.org/WebPage" style="background:url(https://ahxuliangjun.gitee.io/website/images/bg.jpeg);">
  <div class="container use-motion">
    <div class="headband"></div>
<a href="https://gitee.com/ahxuliangjun" target="_blank" rel="noopener" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#70B7FD; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-meta">

    <div>
      <a href="/website/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">徐良军</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
        <p class="site-subtitle">徐良军的博客</p>
  </div>

  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>
</div>


<nav class="site-nav">
  
  <ul id="menu" class="menu">
        <li class="menu-item menu-item-home">

    <a href="/website/" rel="section"><i class="fa fa-fw fa-home"></i>首页</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/website/categories/" rel="section"><i class="fa fa-fw fa-th"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/website/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>归档</a>

  </li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>

</nav>
  <div class="site-search">
    <div class="popup search-popup">
    <div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocorrect="off" autocapitalize="none"
           placeholder="搜索..." spellcheck="false"
           type="text" id="search-input">
  </div>
  <span class="popup-btn-close">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div id="search-result"></div>

</div>
<div class="search-pop-overlay"></div>

  </div>
</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content">
            

  <div class="posts-expand">
      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block " lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://ahxuliangjun.gitee.io/website/website/2019/11/15/2/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="https://himg.bdimg.com/sys/portrait/item/pp.1.d8a0b964.z9ewrAT61w4xKYPMXSO_9g?_t=1573118862410">
      <meta itemprop="name" content="徐良军">
      <meta itemprop="description" content="故其疾如风，其徐如林，侵掠如火，不动如山">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="徐良军">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          PaddlePaddle实现线性回归
        </h1>

        <div class="post-meta">
          
            <i class="fa fa-thumb-tack"></i>
            <font color=ff6800>置顶</font>
            <span class="post-meta-divider">|</span>
          
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>
              

              <time title="创建时间：2019-11-15 17:37:00 / 修改时间：18:31:06" itemprop="dateCreated datePublished" datetime="2019-11-15T17:37:00+08:00">2019-11-15</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/website/categories/PaddlePaddle/" itemprop="url" rel="index">
                    <span itemprop="name">PaddlePaddle</span>
                  </a>
                </span>
            </span>

          
            <div class="post-description">在本次实验中我们将使用PaddlePaddle来搭建一个简单的线性回归模型，并利用这一模型预测你的储蓄（在某地区）可以购买多大面积的房子。并且在学习模型搭建的过程中，了解到机器学习的若干重要概念，掌握一个机器学习预测的基本流程。</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h2 id="PaddlePaddle实现线性回归"><a href="#PaddlePaddle实现线性回归" class="headerlink" title="PaddlePaddle实现线性回归"></a>PaddlePaddle实现线性回归</h2><p>在本次实验中我们将使用PaddlePaddle来搭建一个简单的线性回归模型，并利用这一模型预测你的储蓄（在某地区）可以购买多大面积的房子。并且在学习模型搭建的过程中，了解到机器学习的若干重要概念，掌握一个机器学习预测的基本流程。</p><p><strong>线性回归的基本概念</strong></p><p>线性回归是机器学习中最简单也是最重要的模型之一，其模型建立遵循此流程：获取数据、数据预处理、训练模型、应用模型。</p><a id="more"></a>


<p>回归模型可以理解为：存在一个点集，用一条曲线去拟合它分布的过程。如果拟合曲线是一条直线，则称为线性回归。如果是一条二次曲线，则被称为二次回归。线性回归是回归模型中最简单的一种。</p>
<p>在线性回归中有几个基本的概念需要掌握：</p>
<ul>
<li>假设函数（Hypothesis Function）</li>
<li>损失函数（Loss Function）</li>
<li>优化算法（Optimization Algorithm）</li>
</ul>
<p><strong>假设函数：</strong></p>
<p>假设函数是指，用数学的方法描述自变量和因变量之间的关系，它们之间可以是一个线性函数或非线性函数。 在本次线性回顾模型中，我们的假设函数为 Y^=aX1+b\hat{Y}= aX_1+b<em>Y</em>^=<em>a*<em>X</em>1+*b</em> ，其中，Y^\hat{Y}<em>Y</em>^表示模型的预测结果（预测房价），用来和真实的Y区分。模型要学习的参数即：a,b。</p>
<p><strong>损失函数：</strong></p>
<p>损失函数是指，用数学的方法衡量假设函数预测结果与真实值之间的误差。这个差距越小预测越准确，而算法的任务就是使这个差距越来越小。</p>
<p>建立模型后，我们需要给模型一个优化目标，使得学到的参数能够让预测值Y^\hat{Y}<em>Y</em>^尽可能地接近真实值Y。输入任意一个数据样本的目标值yiy_i<em>y*</em>i*和模型给出的预测值\hat{Y_i，损失函数输出一个非负的实值。这个实值通常用来反映模型误差的大小。</p>
<p>对于线性模型来讲，最常用的损失函数就是均方误差（Mean Squared Error， MSE）。</p>
<p>MSE=1n∑i=1n(Yi^−Yi)2MSE=\frac{1}{n}\sum_{i=1}^{n}(\hat{Y_i}-Y_i)^2<em>M<strong>S</strong>E</em>=<em>n</em>1∑<em>i</em>=1<em>n</em>(<em>Y**i</em>^−<em>Y**i</em>)2</p>
<p>即对于一个大小为n的测试集，MSE是n个数据预测结果误差平方的均值。</p>
<p><strong>优化算法：</strong></p>
<p>在模型训练中优化算法也是至关重要的，它决定了一个模型的精度和运算速度。本章的线性回归实例中主要使用了梯度下降法进行优化。</p>
<p>现在，让我们正式进入实验吧！</p>
<p><strong>首先导入必要的包</strong>，分别是：</p>
<p><strong>paddle.fluid</strong>—&gt;PaddlePaddle深度学习框架</p>
<p><strong>numpy</strong>———-&gt;python基本库，用于科学计算</p>
<p><strong>os</strong>——————&gt;python的模块，可使用该模块对操作系统进行操作</p>
<p><strong>matplotlib</strong>—–&gt;python绘图库，可方便绘制折线图、散点图等图形</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> paddle.fluid <span class="keyword">as</span> fluid</span><br><span class="line"><span class="keyword">import</span> paddle</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br></pre></td></tr></table></figure>

<h3 id="Step1：准备数据。"><a href="#Step1：准备数据。" class="headerlink" title="Step1：准备数据。"></a><strong>Step1：准备数据。</strong></h3><p>（1）uci-housing数据集介绍</p>
<p>数据集共506行,每行14列。前13列用来描述房屋的各种信息，最后一列为该类房屋价格中位数。</p>
<p>PaddlePaddle提供了读取uci_housing训练集和测试集的接口，分别为paddle.dataset.uci_housing.train()和paddle.dataset.uci_housing.test()。</p>
<p>(2)train_reader和test_reader</p>
<p>paddle.reader.shuffle()表示每次缓存BUF_SIZE个数据项，并进行打乱</p>
<p>paddle.batch()表示每BATCH_SIZE组成一个batch</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">BUF_SIZE=<span class="number">500</span></span><br><span class="line">BATCH_SIZE=<span class="number">20</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#用于训练的数据提供器，每次从缓存中随机读取批次大小的数据</span></span><br><span class="line">train_reader = paddle.batch(</span><br><span class="line">    paddle.reader.shuffle(paddle.dataset.uci_housing.train(), </span><br><span class="line">                          buf_size=BUF_SIZE),                    </span><br><span class="line">    batch_size=BATCH_SIZE)   </span><br><span class="line"><span class="comment">#用于测试的数据提供器，每次从缓存中随机读取批次大小的数据</span></span><br><span class="line">test_reader = paddle.batch(</span><br><span class="line">    paddle.reader.shuffle(paddle.dataset.uci_housing.test(),</span><br><span class="line">                          buf_size=BUF_SIZE),</span><br><span class="line">    batch_size=BATCH_SIZE)</span><br></pre></td></tr></table></figure>

<p>(3)打印看下数据是什么样的？PaddlePaddle接口提供的数据已经经过归一化等处理</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#用于打印，查看uci_housing数据</span></span><br><span class="line">train_data=paddle.dataset.uci_housing.train();</span><br><span class="line">sampledata=next(train_data())</span><br><span class="line">print(sampledata)</span><br></pre></td></tr></table></figure>

<h3 id="Step2-网络配置"><a href="#Step2-网络配置" class="headerlink" title="Step2:网络配置"></a><strong>Step2:网络配置</strong></h3><p><strong>（1）网络搭建</strong>：对于线性回归来讲，它就是一个从输入到输出的简单的全连接层。</p>
<p>对于波士顿房价数据集，假设属性和房价之间的关系可以被属性间的线性组合描述。</p>
<p><img src="http://q0sn9so75.bkt.clouddn.com/68.png" alt></p>
<p><img src="http://q0sn9so75.bkt.clouddn.com/69.png" alt></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#定义张量变量x，表示13维的特征值</span></span><br><span class="line">x = fluid.layers.data(name=<span class="string">'x'</span>, shape=[<span class="number">13</span>], dtype=<span class="string">'float32'</span>)</span><br><span class="line"><span class="comment">#定义张量y,表示目标值</span></span><br><span class="line">y = fluid.layers.data(name=<span class="string">'y'</span>, shape=[<span class="number">1</span>], dtype=<span class="string">'float32'</span>)</span><br><span class="line"><span class="comment">#定义一个简单的线性网络,连接输入和输出的全连接层</span></span><br><span class="line"><span class="comment">#input:输入tensor;</span></span><br><span class="line"><span class="comment">#size:该层输出单元的数目</span></span><br><span class="line"><span class="comment">#act:激活函数</span></span><br><span class="line">y_predict=fluid.layers.fc(input=x,size=<span class="number">1</span>,act=<span class="literal">None</span>)</span><br></pre></td></tr></table></figure>

<p><strong>(2)定义损失函数</strong></p>
<p>此处使用均方差损失函数。</p>
<p>square_error_cost(input,lable):接受输入预测值和目标值，并返回方差估计,即为（y-y_predict）的平方</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cost = fluid.layers.square_error_cost(input=y_predict, label=y) <span class="comment">#求一个batch的损失值</span></span><br><span class="line">avg_cost = fluid.layers.mean(cost)                              <span class="comment">#对损失值求平均值</span></span><br></pre></td></tr></table></figure>

<p><strong>(3)定义优化函数</strong></p>
<p>此处使用的是随机梯度下降。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">test_program = fluid.default_main_program().clone(for_test=<span class="literal">True</span>)</span><br><span class="line">optimizer = fluid.optimizer.SGDOptimizer(learning_rate=<span class="number">0.001</span>)</span><br><span class="line">opts = optimizer.minimize(avg_cost)</span><br></pre></td></tr></table></figure>


<p>在上述模型配置完毕后，得到两个fluid.Program：fluid.default_startup_program() 与fluid.default_main_program() 配置完毕了。</p>
<p>参数初始化操作会被写入<strong>fluid.default_startup_program()</strong></p>
<p><strong>fluid.default_main_program</strong>()用于获取默认或全局main program(主程序)。该主程序用于训练和测试模型。fluid.layers 中的所有layer函数可以向 default_main_program 中添加算子和变量。default_main_program 是fluid的许多编程接口（API）的Program参数的缺省值。例如,当用户program没有传入的时候， Executor.run() 会默认执行 default_main_program 。</p>
<h3 id="Step3-模型训练-and-Step4-模型评估"><a href="#Step3-模型训练-and-Step4-模型评估" class="headerlink" title="Step3.模型训练 and Step4.模型评估"></a><strong>Step3.模型训练</strong> and <strong>Step4.模型评估</strong></h3><p><strong>（1）创建Executor</strong></p>
<p>首先定义运算场所 fluid.CPUPlace()和 fluid.CUDAPlace(0)分别表示运算场所为CPU和GPU</p>
<p>Executor:接收传入的program，通过run()方法运行program。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">use_cuda = <span class="literal">False</span>                         <span class="comment">#use_cuda为False,表示运算场所为CPU;use_cuda为True,表示运算场所为GPU           </span></span><br><span class="line">place = fluid.CUDAPlace(<span class="number">0</span>) <span class="keyword">if</span> use_cuda <span class="keyword">else</span> fluid.CPUPlace()</span><br><span class="line">exe = fluid.Executor(place)              <span class="comment">#创建一个Executor实例exe</span></span><br><span class="line">exe.run(fluid.default_startup_program()) <span class="comment">#Executor的run()方法执行startup_program(),进行参数初始化</span></span><br></pre></td></tr></table></figure>

<p><strong>（2）定义输入数据维度</strong></p>
<p>DataFeeder负责将数据提供器（train_reader,test_reader）返回的数据转成一种特殊的数据结构，使其可以输入到Executor中。</p>
<p>feed_list设置向模型输入的向变量表或者变量表名</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 定义输入数据维度</span></span><br><span class="line">feeder = fluid.DataFeeder(place=place, feed_list=[x, y])<span class="comment">#feed_list:向模型输入的变量表或变量表名</span></span><br></pre></td></tr></table></figure>

<p><strong>（3）定义绘制训练过程的损失值变化趋势的方法draw_train_process</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">iter=<span class="number">0</span>;</span><br><span class="line">iters=[]</span><br><span class="line">train_costs=[]</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">draw_train_process</span><span class="params">(iters,train_costs)</span>:</span></span><br><span class="line">    title=<span class="string">"training cost"</span></span><br><span class="line">    plt.title(title, fontsize=<span class="number">24</span>)</span><br><span class="line">    plt.xlabel(<span class="string">"iter"</span>, fontsize=<span class="number">14</span>)</span><br><span class="line">    plt.ylabel(<span class="string">"cost"</span>, fontsize=<span class="number">14</span>)</span><br><span class="line">    plt.plot(iters, train_costs,color=<span class="string">'red'</span>,label=<span class="string">'training cost'</span>) </span><br><span class="line">    plt.grid()</span><br><span class="line">    plt.show()</span><br></pre></td></tr></table></figure>

<p><strong>（4）训练并保存模型</strong></p>
<p>Executor接收传入的program,并根据feed map(输入映射表)和fetch_list(结果获取表) 向program中添加feed operators(数据输入算子)和fetch operators（结果获取算子)。 feed map为该program提供输入数据。fetch_list提供program训练结束后用户预期的变量。</p>
<p>使用feed方式送入训练数据，先将reader数据转换为PaddlePaddle可识别的Tensor数据，传入执行器进行训练。</p>
<p>注：enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列，同时列出数据和数据下标，</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">EPOCH_NUM=<span class="number">50</span></span><br><span class="line">model_save_dir = <span class="string">"/home/aistudio/work/fit_a_line.inference.model"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> pass_id <span class="keyword">in</span> range(EPOCH_NUM):                                  <span class="comment">#训练EPOCH_NUM轮</span></span><br><span class="line">    <span class="comment"># 开始训练并输出最后一个batch的损失值</span></span><br><span class="line">    train_cost = <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> batch_id, data <span class="keyword">in</span> enumerate(train_reader()):              <span class="comment">#遍历train_reader迭代器</span></span><br><span class="line">        train_cost = exe.run(program=fluid.default_main_program(),<span class="comment">#运行主程序</span></span><br><span class="line">                             feed=feeder.feed(data),              <span class="comment">#喂入一个batch的训练数据，根据feed_list和data提供的信息，将输入数据转成一种特殊的数据结构</span></span><br><span class="line">                             fetch_list=[avg_cost])    </span><br><span class="line">        <span class="keyword">if</span> batch_id % <span class="number">40</span> == <span class="number">0</span>:</span><br><span class="line">            print(<span class="string">"Pass:%d, Cost:%0.5f"</span> % (pass_id, train_cost[<span class="number">0</span>][<span class="number">0</span>]))    <span class="comment">#打印最后一个batch的损失值</span></span><br><span class="line">        iter=iter+BATCH_SIZE</span><br><span class="line">        iters.append(iter)</span><br><span class="line">        train_costs.append(train_cost[<span class="number">0</span>][<span class="number">0</span>])</span><br><span class="line">       </span><br><span class="line">   </span><br><span class="line">    <span class="comment"># 开始测试并输出最后一个batch的损失值</span></span><br><span class="line">    test_cost = <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> batch_id, data <span class="keyword">in</span> enumerate(test_reader()):               <span class="comment">#遍历test_reader迭代器</span></span><br><span class="line">        test_cost= exe.run(program=test_program, <span class="comment">#运行测试cheng</span></span><br><span class="line">                            feed=feeder.feed(data),               <span class="comment">#喂入一个batch的测试数据</span></span><br><span class="line">                            fetch_list=[avg_cost])                <span class="comment">#fetch均方误差</span></span><br><span class="line">    print(<span class="string">'Test:%d, Cost:%0.5f'</span> % (pass_id, test_cost[<span class="number">0</span>][<span class="number">0</span>]))     <span class="comment">#打印最后一个batch的损失值</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">#保存模型</span></span><br><span class="line">    <span class="comment"># 如果保存路径不存在就创建</span></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">not</span> os.path.exists(model_save_dir):</span><br><span class="line">    os.makedirs(model_save_dir)</span><br><span class="line"><span class="keyword">print</span> (<span class="string">'save models to %s'</span> % (model_save_dir))</span><br><span class="line"><span class="comment">#保存训练参数到指定路径中，构建一个专门用预测的program</span></span><br><span class="line">fluid.io.save_inference_model(model_save_dir,   <span class="comment">#保存推理model的路径</span></span><br><span class="line">                                  [<span class="string">'x'</span>],            <span class="comment">#推理（inference）需要 feed 的数据</span></span><br><span class="line">                                  [y_predict],      <span class="comment">#保存推理（inference）结果的 Variables</span></span><br><span class="line">                                  exe)              <span class="comment">#exe 保存 inference model</span></span><br><span class="line">draw_train_process(iters,train_costs)</span><br></pre></td></tr></table></figure>

<h3 id="Step5-模型预测"><a href="#Step5-模型预测" class="headerlink" title="Step5.模型预测"></a><strong>Step5.模型预测</strong></h3><p><strong>（1）创建预测用的Executor</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">infer_exe = fluid.Executor(place)    <span class="comment">#创建推测用的executor</span></span><br><span class="line">inference_scope = fluid.core.Scope() <span class="comment">#Scope指定作用域</span></span><br></pre></td></tr></table></figure>

<p><strong>（2）可视化真实值与预测值方法定义</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">infer_results=[]</span><br><span class="line">groud_truths=[]</span><br><span class="line"></span><br><span class="line"><span class="comment">#绘制真实值和预测值对比图</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">draw_infer_result</span><span class="params">(groud_truths,infer_results)</span>:</span></span><br><span class="line">    title=<span class="string">'Boston'</span></span><br><span class="line">    plt.title(title, fontsize=<span class="number">24</span>)</span><br><span class="line">    x = np.arange(<span class="number">1</span>,<span class="number">20</span>) </span><br><span class="line">    y = x</span><br><span class="line">    plt.plot(x, y)</span><br><span class="line">    plt.xlabel(<span class="string">'ground truth'</span>, fontsize=<span class="number">14</span>)</span><br><span class="line">    plt.ylabel(<span class="string">'infer result'</span>, fontsize=<span class="number">14</span>)</span><br><span class="line">    plt.scatter(groud_truths, infer_results,color=<span class="string">'green'</span>,label=<span class="string">'training cost'</span>) </span><br><span class="line">    plt.grid()</span><br><span class="line">    plt.show()</span><br></pre></td></tr></table></figure>

<p><strong>(3)开始预测</strong></p>
<p>通过fluid.io.load_inference_model，预测器会从params_dirname中读取已经训练好的模型，来对从未遇见过的数据进行预测。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">with</span> fluid.scope_guard(inference_scope):<span class="comment">#修改全局/默认作用域（scope）, 运行时中的所有变量都将分配给新的scope。</span></span><br><span class="line">    <span class="comment">#从指定目录中加载 推理model(inference model)</span></span><br><span class="line">    [inference_program,                             <span class="comment">#推理的program</span></span><br><span class="line">     feed_target_names,                             <span class="comment">#需要在推理program中提供数据的变量名称</span></span><br><span class="line">     fetch_targets] = fluid.io.load_inference_model(<span class="comment">#fetch_targets: 推断结果</span></span><br><span class="line">                                    model_save_dir, <span class="comment">#model_save_dir:模型训练路径 </span></span><br><span class="line">                                    infer_exe)      <span class="comment">#infer_exe: 预测用executor</span></span><br><span class="line">    <span class="comment">#获取预测数据</span></span><br><span class="line">    infer_reader = paddle.batch(paddle.dataset.uci_housing.test(),  <span class="comment">#获取uci_housing的测试数据</span></span><br><span class="line">                          batch_size=<span class="number">200</span>)                           <span class="comment">#从测试数据中读取一个大小为200的batch数据</span></span><br><span class="line">    <span class="comment">#从test_reader中分割x</span></span><br><span class="line">    test_data = next(infer_reader())</span><br><span class="line">    test_x = np.array([data[<span class="number">0</span>] <span class="keyword">for</span> data <span class="keyword">in</span> test_data]).astype(<span class="string">"float32"</span>)</span><br><span class="line">    test_y= np.array([data[<span class="number">1</span>] <span class="keyword">for</span> data <span class="keyword">in</span> test_data]).astype(<span class="string">"float32"</span>)</span><br><span class="line">    results = infer_exe.run(inference_program,                              <span class="comment">#预测模型</span></span><br><span class="line">                            feed=&#123;feed_target_names[<span class="number">0</span>]: np.array(test_x)&#125;,  <span class="comment">#喂入要预测的x值</span></span><br><span class="line">                            fetch_list=fetch_targets)                       <span class="comment">#得到推测结果 </span></span><br><span class="line">                            </span><br><span class="line">    print(<span class="string">"infer results: (House Price)"</span>)</span><br><span class="line">    <span class="keyword">for</span> idx, val <span class="keyword">in</span> enumerate(results[<span class="number">0</span>]):</span><br><span class="line">        print(<span class="string">"%d: %.2f"</span> % (idx, val))</span><br><span class="line">        infer_results.append(val)</span><br><span class="line">    print(<span class="string">"ground truth:"</span>)</span><br><span class="line">    <span class="keyword">for</span> idx, val <span class="keyword">in</span> enumerate(test_y):</span><br><span class="line">        print(<span class="string">"%d: %.2f"</span> % (idx, val))</span><br><span class="line">        groud_truths.append(val)</span><br><span class="line">    draw_infer_result(groud_truths,infer_results)</span><br></pre></td></tr></table></figure>












    </div>

    
    
    

    <div>
      
        
<div class="my_post_copyright">
  <script src="//cdn.bootcss.com/clipboard.js/1.5.10/clipboard.min.js"></script>
  
  <!-- JS库 sweetalert 可修改路径 -->
  <script src="https://cdn.bootcss.com/jquery/2.0.0/jquery.min.js"></script>
  <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
  <p><span>本文标题:</span><a href="/website/2019/11/15/2/">PaddlePaddle实现线性回归</a></p>
  <p><span>文章作者:</span><a href="/" title="访问 徐良军 的个人博客">徐良军</a></p>
  <p><span>发布时间:</span>2019年11月15日 - 17:11</p>
  <p><span>最后更新:</span>2019年11月15日 - 18:11</p>
  <p><span>原始链接:</span><a href="/website/2019/11/15/2/" title="PaddlePaddle实现线性回归">https://ahxuliangjun.gitee.io/website/2019/11/15/2/</a>
    <span class="copy-path"  title="点击复制文章链接"><i class="fa fa-clipboard" data-clipboard-text="https://ahxuliangjun.gitee.io/website/2019/11/15/2/"  aria-label="复制成功！"></i></span>
  </p>
  <p><span>许可协议:</span><i class="fa fa-creative-commons"></i> 转载请保留原文链接及作者。</p>  
</div>
<script> 
    var clipboard = new Clipboard('.fa-clipboard');
    $(".fa-clipboard").click(function(){
      clipboard.on('success', function(){
        swal({   
          title: "",   
          text: '复制成功',
          icon: "success", 
          showConfirmButton: true
          });
    });
    });  
</script>

      
    </div>
      
        <div class="reward-container">
  <div></div>
  <button disable="enable" onclick="var qr = document.getElementById(&quot;qr&quot;); qr.style.display = (qr.style.display === 'none') ? 'block' : 'none';">
    打赏
  </button>
  <div id="qr" style="display: none;">
      
      <div style="display: inline-block;">
        <img src="/website/images/wechatpay.jpeg" alt="徐良军 微信支付">
        <p>微信支付</p>
      </div>
      
      <div style="display: inline-block;">
        <img src="/website/images/alipay.jpeg" alt="徐良军 支付宝">
        <p>支付宝</p>
      </div>

  </div>
</div>


      <footer class="post-footer">
          
          <div class="post-tags">
              <a href="/website/tags/AI-Studio-Paddle-%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92/" rel="tag"><i class="fa fa-tag"></i> -AI Studio -Paddle -线性回归</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-next post-nav-item">
                <a href="/website/2019/11/07/1/" rel="next" title="码云 + Hexo 搭建个人博客">
                  <i class="fa fa-chevron-left"></i> 码云 + Hexo 搭建个人博客
                </a>
            </div>

            <span class="post-nav-divider"></span>

            <div class="post-nav-prev post-nav-item">
                <a href="/website/2020/01/16/3/" rel="prev" title="分享一个vue3的项目模板">
                  分享一个vue3的项目模板 <i class="fa fa-chevron-right"></i>
                </a>
            </div>
          </div>
      </footer>
    
  </article>
  
  
  

  </div>


          </div>
          
    
  <div class="comments" id="comments">
    <div id="lv-container" data-id="city" data-uid="MTAyMC80NzQxNi8yMzkxNg=="></div>
  </div>
  

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#PaddlePaddle实现线性回归"><span class="nav-number">1.</span> <span class="nav-text">PaddlePaddle实现线性回归</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Step1：准备数据。"><span class="nav-number">1.1.</span> <span class="nav-text">Step1：准备数据。</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Step2-网络配置"><span class="nav-number">1.2.</span> <span class="nav-text">Step2:网络配置</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Step3-模型训练-and-Step4-模型评估"><span class="nav-number">1.3.</span> <span class="nav-text">Step3.模型训练 and Step4.模型评估</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Step5-模型预测"><span class="nav-number">1.4.</span> <span class="nav-text">Step5.模型预测</span></a></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <img class="site-author-image" itemprop="image" alt="徐良军"
    src="https://himg.bdimg.com/sys/portrait/item/pp.1.d8a0b964.z9ewrAT61w4xKYPMXSO_9g?_t=1573118862410">
  <p class="site-author-name" itemprop="name">徐良军</p>
  <div class="site-description" itemprop="description">故其疾如风，其徐如林，侵掠如火，不动如山</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/website/archives/">
        
          <span class="site-state-item-count">3</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/website/categories/">
          
        <span class="site-state-item-count">3</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">3</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>
  <div class="feed-link motion-element">
    <a href="/website/atom.xml" rel="alternate">
      <i class="fa fa-rss"></i>RSS
    </a>
  </div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://gitee.com/ahxuliangjun" title="Git &amp;rarr; https:&#x2F;&#x2F;gitee.com&#x2F;ahxuliangjun" rel="noopener" target="_blank"><i class="fa fa-fw fa-github"></i>Git</a>
      </span>
      <span class="links-of-author-item">
        <a href="http://wpa.qq.com/msgrd?v=3&uin=690242231&site=qq&menu=yes" title="QQ &amp;rarr; http:&#x2F;&#x2F;wpa.qq.com&#x2F;msgrd?v=3&amp;uin=690242231&amp;site=qq&amp;menu=yes" rel="noopener" target="_blank"><i class="fa fa-fw fa-qq"></i>QQ</a>
      </span>
      <span class="links-of-author-item">
        <a href="/website/mailto:690242231@qq.com" title="E-Mail &amp;rarr; mailto:690242231@qq.com" rel="noopener" target="_blank"><i class="fa fa-fw fa-envelope"></i>E-Mail</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://weibo.com/u/1548377403" title="Weibo &amp;rarr; https:&#x2F;&#x2F;weibo.com&#x2F;u&#x2F;1548377403" rel="noopener" target="_blank"><i class="fa fa-fw fa-weibo"></i>Weibo</a>
      </span>
  </div>


  <div class="links-of-blogroll motion-element">
    <div class="links-of-blogroll-title">
      <i class="fa fa-fw fa-link"></i>
      友情连接
    </div>
    <ul class="links-of-blogroll-list">
        <li class="links-of-blogroll-item">
          <a href="https://www.oschina.net/" title="https:&#x2F;&#x2F;www.oschina.net&#x2F;" rel="noopener" target="_blank">开源中国</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="https://www.baidu.com/" title="https:&#x2F;&#x2F;www.baidu.com" rel="noopener" target="_blank">百度</a>
        </li>
    </ul>
  </div>

      </div>
      
      <iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=86 src="//music.163.com/outchain/player?type=2&id=167850&auto=1&height=66"></iframe>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-angellist"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">徐良军</span>
  <span><i class="fa fa-user"></i></span>
  <span> 博客全站共8.7k字</span>
  
  <!--
  <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
  <i class="fa fa-user-md"></i>
  <span id="busuanzi_container_site_pv">
    本站访问量:<span id="busuanzi_value_site_pv"></span>次
  </span>
  <span class="post-meta-divider">|</span>
  <span id="busuanzi_container_site_uv">
    本站总访客量：<span id="busuanzi_value_site_uv"></span>人
  </span>
  -->
</div>
<!-- 用下面的符号注释，注释代码用下面括号括起来 -->
<!-- -->
<!--
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> 强力驱动 v4.0.0
  </div>
  <span class="post-meta-divider">|</span>
  <div class="theme-info">主题 – <a href="https://theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Gemini</a> v7.5.0
  </div>
-->
  <div class="addthis_inline_share_toolbox">
    <script src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5dc7a702c422599d" async="async"></script>
  </div>

        












        
      </div>
    </footer>
  </div>

  
  <script src="/website/lib/anime.min.js"></script>
  <script src="/website/lib/velocity/velocity.min.js"></script>
  <script src="/website/lib/velocity/velocity.ui.min.js"></script>
<script src="/website/js/utils.js"></script><script src="/website/js/motion.js"></script>
<script src="/website/js/schemes/pisces.js"></script>
<script src="/website/js/next-boot.js"></script>



  
  <script>
    (function(){
      var bp = document.createElement('script');
      var curProtocol = window.location.protocol.split(':')[0];
      bp.src = (curProtocol === 'https') ? 'https://zz.bdstatic.com/linksubmit/push.js' : 'http://push.zhanzhang.baidu.com/push.js';
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(bp, s);
    })();
  </script>




  <script src="/website/js/local-search.js"></script>













  

  

<script>
  window.livereOptions = {
    refer: location.pathname.replace(CONFIG.root, '').replace('index.html', '')
  };
  (function(d, s) {
    var j, e = d.getElementsByTagName(s)[0];
    if (typeof LivereTower === 'function') { return; }
    j = d.createElement(s);
    j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
    j.async = true;
    e.parentNode.insertBefore(j, e);
  })(document, 'script');
</script>

</body>
</html>
<!-- 动态背景 -->
<script type="text/javascript" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script>
<!-- 页面点击小红心 -->
<script type="text/javascript" src="https://ahxuliangjun.gitee.io/website/js/src/clicklove.js"></script>

<!-- -->
<!-- weather js -->
<div id="tp-weather-widget"></div>
<script>
  (function(a,h,g,f,e,d,c,b){b=function(){d=h.createElement(g);c=h.getElementsByTagName(g)[0];d.src=e;d.charset="utf-8";d.async=1;c.parentNode.insertBefore(d,c)};a["SeniverseWeatherWidgetObject"]=f;a[f]||(a[f]=function(){(a[f].q=a[f].q||[]).push(arguments)});a[f].l=+new Date();if(a.attachEvent){a.attachEvent("onload",b)}else{a.addEventListener("load",b,false)}}(window,document,"script","SeniverseWeatherWidget","//cdn.sencdn.com/widget2/static/js/bundle.js?t="+parseInt((new Date().getTime() / 100000000).toString(),10)));
  window.SeniverseWeatherWidget('show', {
    flavor: "bubble",
    location: "WTW3SJ5ZBJUY",
    geolocation: true,
    language: "zh-Hans",
    unit: "c",
    theme: "dark",
    token: "762787a3-c72c-414e-995d-b44bfcd6b5e0",
    hover: "enabled",
    container: "tp-weather-widget"
  })
</script>
